/*
* (c) 2014 University of Applied Sciences, Karlsruhe
* Project "Segmentation of depth data of a plenoptic camera"
* summer semester 2014
*
* ransac.h
* This file contains several implementations of the RANSAC algorithm.
*/

#ifndef _RANSAC_H_
#define _RANSAC_H_

#include <vector>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/common/distances.h>


namespace sgMain
{
	namespace Segmentation
	{
		/**
		Creates a random sample by randomly selecting a number of items out of a set of numbers 0 - x.
		\param[in] numOfElements The size of the number set out of which the random sample can be selected.
		\param[in] elementsToPick How many elements should be selected.
		\return The list of selected elements.
		*/
		std::vector<size_t> CreateRandomSample(size_t numOfElements, size_t elementsToPick);

		/**
		RANSAC for 2D applications (detects lines in a depth map). 
		\param[in] pointCloud The 2D point cloud onto which the segmentation should be performed. To process an image, create a point for each pixel
		which is not zero and pass the resulting point cloud. z values are ignored.
		\param[out] rest The remaining points which do not belong to any segmented object.
		\param[out] segmentedObject A list of found objects. Each item consists of a set of points which together are the best fit for the line model.
		\param[in] treshold The threshold in percent (number of points segmented / total number of points) after which the algorithm terminates.
		\param[in] maxNumberOfIterations The maximum number of iterations after which the algorithm terminates even if the treshold has not been reached.
		\param[in] triesPerIteration How many times a new random sample is selected per iteration.
		\return 0 if successful, -1 if not enough points are given
		*/
		int RANSAC2D(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &pointCloud,
			pcl::PointCloud<pcl::PointXYZRGB>::Ptr &rest,
			std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> &segmentedObjects,
			double treshold, unsigned int maxNumberOfIterations, unsigned int triesPerIteration);

		/**
		RANSAC for 3D segmentation requirements.
		\param[in] cloud The 3D point cloud onto which the segmentation should be performed.
		\param[out] rest The remaining points which do not belong to any segmented object.
		\param[out] segmentedObject A list of found objects. Each item consists of a set of points which together are the best fit for the line model.
		\param[in] treshold The threshold in percent (number of points segmented / total number of points) after which the algorithm terminates.
		\param[in] modelType The model which is searched for.
		\param[in] methodType The type of RANSAC algorithm used.
		\return 0 if successful, -1 if segmentation failed.
		*/
		int RANSAC3D(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud,
			pcl::PointCloud<pcl::PointXYZRGB>::Ptr &rest,
			std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> &segmentedObjects,
			float treshold, pcl::SacModel modelType = pcl::SACMODEL_PLANE, int methodType = pcl::SAC_RANSAC);
	}
}
#endif